import cv2
import numpy as np


def moon_shape(img_path):
    img = cv2.imread(img_path, 0)

    # 阈值化图像
    ret, thresh = cv2.threshold(img, 90, 255, cv2.THRESH_BINARY)

    # 检测图像中的圆
    circles = cv2.HoughCircles(thresh, cv2.HOUGH_GRADIENT, 1, 20, param1=80, param2=10, minRadius=15, maxRadius=30)

    # 平滑和边缘检测图像以检测可能的月牙形  #TODO

    # 在原始图像上绘图
    if circles is not None:
        circles = np.round(circles[0, :]).astype('int')
        for (x, y, r) in circles:
            cv2.circle(img, (x, y), r, (255, 255, 255), 2)

    # 显示结果
    cv2.imshow('result', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


def moon_shape2(img_path):
    img = cv2.imread(img_path, 0)
    kernel = np.ones((2, 2), np.uint8)
    # 进行形态学操作
    morph = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

    # 阈值化处理
    ret, thresh = cv2.threshold(morph, 254, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    cv2.imshow('result-thresh', thresh)
    cv2.waitKey(0)

    # 使用轮廓检测来识别检测到的月牙形区域
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 绘制找到的轮廓
    cv2.drawContours(img, contours, -1, (0, 0, 255), 3)

    # 显示结果
    cv2.imshow('result', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


def moon_shape3(img_path):
    img = cv2.imread(img_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 二值化处理
    ret, thresh = cv2.threshold(gray, 254, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    # 使用轮廓检测来识别检测到的月牙形区域
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 遍历轮廓，找到月牙形的轮廓并在原图标注
    for cnt in contours:
        # 计算面积和周长
        area = cv2.contourArea(cnt)
        perimeter = cv2.arcLength(cnt, True)
        if area < 200 or perimeter < 100:
            continue

        # 计算轮廓的凸包
        hull = cv2.convexHull(cnt, returnPoints=False)
        hull[::-1].sort(axis=0)
        # 检查新轮廓中是否存在缺陷
        defects = cv2.convexityDefects(cnt, hull)
        if defects is None:
            continue

        # 若缺陷数量大于等于2，就认为该轮廓具有月牙形
        if defects.shape[0] >= 2:
            x, y, w, h = cv2.boundingRect(cnt)
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

    # 显示结果
    cv2.imshow('result', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':
    img_path = r'./data/202302/01.jpg'
    # moon_shape(img_path)
    moon_shape2(img_path)
    moon_shape3(img_path)
